package com.ysstech.common.service;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ysstech.common.cache.RedisCacheManager;
import com.ysstech.common.entity.Holiday;
import com.ysstech.common.mapper.HolidayMapper;
import com.ysstech.common.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

@Slf4j
@Service
public class HolidayService extends ServiceImpl<HolidayMapper, Holiday> {
    @Autowired
    private RedisCacheManager redisCacheManager;

    /**
     * 判断是不是工作日
     *
     * @return
     */
    public Boolean isWorkDay(String today) throws Exception {
        try {
            List<String> list = queryAllHoliday(today);
            if (!list.contains(today)) { //是节假日
                return true;
            }
        } catch (Exception ex) {
            log.error("判断是不是工作日出错" + ex.toString());
            throw new Exception("判断是不是工作日出错，请稍后重试！");
        }
        return false;
    }


    /**
     * 获取计划激活日期
     *
     * @param today opening date
     * @param num   num个工作日后
     * @return
     * @throws Exception
     */
    public String getNextWorkday(String today, int num) throws Exception {
        try {
            Date date = getNextWorkday(DateUtil.strToDate(today), queryAllHoliday(today), num);
            return DateUtil.dateToStr(date);
        } catch (Exception ex) {
            log.error("获取工作日出错" + ex.toString());
            throw new Exception("获取工作日出错，请稍后重试！");
        }
    }

    /**
     * 获取所有的节假日信息
     *
     * @param today
     * @return
     * @throws Exception
     */
    private List<String> queryAllHoliday(String today) throws Exception {
        List<String> list = new ArrayList<>();
        try {
            String year = DateUtil.getSysYear(DateUtil.strToDate(today));
            //存放holiday的每一天
            if (redisCacheManager.exists(year + "HOLIDAY")) {
                list = (List<String>) redisCacheManager.getCache(year + "HOLIDAY");
            } else {
                QueryWrapper<Holiday> wrapper = new QueryWrapper<>();
                wrapper.select("HOLIDAY");
                List<Holiday> listHoliday = this.list(wrapper);
                if (CollectionUtils.isEmpty(listHoliday)) {
                    return null;
                }
                for (Holiday holiday : listHoliday) {
                    if (null == holiday) {
                        continue;
                    }
                    list.add(holiday.getHoliday());
                }
                redisCacheManager.putCache(year + "HOLIDAY", list);
            }
        } catch (Exception ex) {
            log.error("获取工作日出错");
            throw new Exception("获取工作日出错，请稍后重试！");
        }
        return list;
    }

    /**
     * 获取计划激活日期
     *
     * @param today opening date
     * @param list  holidayList
     * @param num   num个工作日后
     * @return
     * @throws ParseException
     */
    public static Date getNextWorkday(Date today, List<String> list, int num) throws Exception {
        Date tomorrow = null;
        int delay = 1;
        while (delay <= Math.abs(num)) {
            if (num > 0) {
                tomorrow = getTomorrow(today, true);
            } else {
                tomorrow = getTomorrow(today, false);
            }
            if (!list.contains(DateUtil.dateToStr(tomorrow))) { //是节假日
                delay++;
            }
            today = tomorrow;
        }
        return today;
    }

    /**
     * 获取tomorrow的日期
     *
     * @param date
     * @return
     */
    public static Date getTomorrow(Date date, boolean next) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        if (next) {
            calendar.add(Calendar.DAY_OF_MONTH, +1);
        } else {
            calendar.add(Calendar.DAY_OF_MONTH, -1);
        }
        date = calendar.getTime();
        return date;
    }


    /**
     * 判断是否是weekend
     *
     * @param sdate
     * @return
     * @throws Exception
     */
    public static boolean isWeekend(String sdate) throws Exception {
        Date date = DateUtil.strToDate(sdate);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 判断是否是weekend
     *
     * @param sdate
     * @return
     * @throws Exception
     */
    public static String isWeek(String sdate) throws Exception {
        Date date = DateUtil.strToDate(sdate);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) { //星期六
            return "1";
        } else if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) { //星期天
            return "2";
        }
        return null;
    }

    /**
     * 读取文件里节假日
     *
     * @param file
     */
    /*public static List<Holiday> readHolidayFile(File file) throws Exception {
        List<Holiday> listHoliday = new ArrayList<>();
        try {
            List<List<Object>> all = FileUtil.readerExcelObj(file);
            Map<String, Holiday> holidayMap = new HashMap<>();
            Map<String, String> takeworkMap = new HashMap<>();
            String fyear = "";
            for (int i = 1; i < all.size(); i++) {
                List<Object> list = all.get(i);
                if (null != list.get(0) && "" != list.get(0)) {
                    if (StringUtils.isBlank(fyear)) {
                        fyear = DateUtil.getSysYear(DateUtil.strToDate(String.valueOf(list.get(0))));
                    }
                    String date = DateUtil.dateToStr(DateUtil.strToDate(String.valueOf(list.get(0))));
                    Holiday holiday1 = new Holiday();
                    holiday1.setHoliday(date);
                    holiday1.setDescription("法定节假日");
                    holidayMap.put(date, holiday1);//法定节假日
                }
                if (null != list.get(1) && "" != list.get(1)) {
                    String date = DateUtil.dateToStr(DateUtil.strToDate(String.valueOf(list.get(0))));
                    takeworkMap.put(date, date);//调休日
                }
            }
            if (StringUtils.isBlank(fyear)) {
                log.error("获取年份出错！");
                return listHoliday;
            }
            //一年当中的星期六星期天
            String starttime = DateUtil.dateToStr(DateUtil.getYearFirst(Integer.valueOf(fyear)));
            String endtime = DateUtil.dateToStr(DateUtil.getYearLast(Integer.valueOf(fyear)));
            Map<String, Holiday> weekMap = new HashMap<>();
            while (!starttime.equals(endtime)) {
                Date tomorrow = HolidayUtils.getTomorrow(DateUtil.strToDate(starttime), true);
                starttime = DateUtil.dateToStr(tomorrow);
                //判断是否是周末
                String isweek = isWeek(starttime);
                if ("1".equals(isweek) || "2".equals(isweek)) {  //周末插入一条数据到数据
                    Holiday holiday1 = new Holiday();
                    holiday1.setHoliday(starttime);
                    holiday1.setDescription("1".equals(isweek) ? "星期六" : "星期天");
                    weekMap.put(starttime, holiday1);
                }
            }
            weekMap.putAll(holidayMap);  //添加当年法定节假日
            weekMap.remove(takeworkMap); //删除调休日
            for (Map.Entry<String, Holiday> info : weekMap.entrySet()) {
                Holiday day = info.getValue();
                day.setDatatime(DateUtil.dateToStrByFormat(new Date(), "yyyy-MM-dd HH:mm:ss"));
                listHoliday.add(info.getValue());
            }
        } catch (Exception e) {
            log.error("获取节假日失败！");
            throw new Exception("获取节假日出错，请稍后重试！");
        }
        return listHoliday;
    }*/
}
